package com.gitee.wsl.ext.list

fun List<Float>.floatLimits(): Pair<Float, Float> {

    val min = min()
    var max = max()

    if (min == max)
        max += 1F

    return Pair(min, max)
}

/**
 * Return the first non-null value returned by [transform].
 * Generate an index-based loop that doesn't use an [Iterator].
 */
inline fun <R, T> List<R>.firstNotNullOfOrNullIndices(transform: (R) -> T?): T? {
    for (i in indices) {
        transform(get(i))?.let { return it }
    }
    return null
}


fun <T : Comparable<T>> List<T>.quickSelect(k: Int): T {
    if (k < 0 || k >= size) throw IndexOutOfBoundsException("k = $k, size = $size")

    var list = this
    var temp = mutableListOf<T>()
    var less = mutableListOf<T>()
    var k = k
    var greater = mutableListOf<T>()
    while (list.size > 1) {
        var equal = 0
        val x = list.random()
        greater.clear()
        less.clear()
        for (v in list) {
            val comp = v.compareTo(x)
            when {
                comp < 0 -> less.add(v)
                comp > 0 -> greater.add(v)
                else -> equal++
            }
        }
        when {
            k < less.size -> {
                list = less
                less = temp
                temp = list
            }
            k < less.size + equal -> {
                return x
            }
            else -> {
                list = greater
                greater = temp
                temp = list
                k -= less.size + equal
            }
        }
    }
    return list[0]
}

fun <T> List<T>.last(count: Int) = subList(size - count, size)

fun <T> List<T>.getRepeating(index: Int): T {
    if (isEmpty()) throw IllegalStateException()
    return get(index % size.coerceAtLeast(1))
}
